// 图片裁剪
<template>
  <div class="UploadImg">
    <a-modal :visible="isUploadImg" @cancel="isUploadImg = false,option.img = ''" :footer="null" class="previewVisible" width="1000">
      <a-card >
        <a-spin :spinning="spinning">
          <div style="min-width: 1750px;display: flex;align-items: end;justify-content: space-evenly;">
            <div class="cut">
              <vue-cropper
                ref="cropper"
                :img="option.img"
                :output-size="option.size"
                :output-type="option.outputType"
                :info="true"
                :full="option.full"
                :can-move="option.canMove"
                :can-move-box="option.canMoveBox"
                :fixed-box="option.fixedBox"
                :original="option.original"
                :auto-crop="option.autoCrop"
                :auto-crop-width="option.autoCropWidth"
                :auto-crop-height="option.autoCropHeight"
                :center-box="option.centerBox"
                @real-time="realTime"
                :high="option.high"
              ></vue-cropper>
            </div>
            <!-- <div
            class="show-preview"
            :style="{ width: previews.w + 'px', height: previews.h + 'px', overflow: 'hidden', margin: '5px' }"
            >
              <div :style="previews.div">
                <img :src="previews.url" :style="previews.img" />
              </div>
            </div> -->
            <div class="test-button">
              <div>
                <button @click="changeImg" class="btn">切换</button>
              </div>
              <div>
                <label class="btn" for="uploads">上传图片</label>
                <input
                  type="file"
                  id="uploads"
                  style="position:absolute; clip:rect(0 0 0 0);"
                  accept="image/png, image/jpeg, image/gif, image/jpg"
                  @change="uploadImg($event, 1)"
                />
              </div>
              <div>
                <button @click="clearCrop" class="btn">清除截图</button>
              </div>
              <div>
                <button @click="refreshCrop" class="btn">重置</button>
              </div>
              <div>
                <button @click="changeScale(1)" class="btn">放大</button>
              </div>
              <div>
                <button @click="changeScale(-1)" class="btn">缩小</button>
              </div>
              <div>
                <button @click="rotateLeft" class="btn">左旋转</button>
              </div>
              <div>
                <button @click="rotateRight" class="btn">右旋转</button>
              </div>
              <div>
                <button @click="finish('base64')" class="btn">预览(base64)</button>
              </div>
              <div>
                <button @click="finish('blob')" class="btn">预览(blob)</button>
              </div>
              <div>
                <a @click="down('base64')" class="btn">下载(base64)</a>
              </div>
              <div>
                <a @click="down('blob')" class="btn">下载(blob)</a>
              </div>
              <button @click="submit" class="btn">确定</button>
              <div style="display:block; width: 100%;">
                <label class="c-item">
                  <span>上传图片是否显示原始宽高 (针对大图 可以铺满)</span>
                  <input type="checkbox" v-model="option.original" />
                  <span>original: {{ option.original }}</span>
                </label>
                <label class="c-item">
                  <span>能否拖动图片</span>
                  <input type="checkbox" v-model="option.canMove" />
                </label>
                <label class="c-item">
                  <span>能否拖动截图框</span>
                  <input type="checkbox" v-model="option.canMoveBox" />
                  <span>canMoveBox: {{ option.canMoveBox }}</span>
                </label>
                <label class="c-item">
                  <span>截图框固定大小</span>
                  <input type="checkbox" v-model="option.fixedBox" />
                  <span>fixedBox: {{ option.fixedBox }}</span>
                </label>
                <label class="c-item">
                  <span>是否输出原图比例的截图</span>
                  <input type="checkbox" v-model="option.full" />
                  <span>full: {{ option.full }}</span>
                </label>
                <label class="c-item">
                  <span>是否自动生成截图框</span>
                  <input type="checkbox" v-model="option.autoCrop" />
                  <span>autoCrop: {{ option.autoCrop }}</span>
                </label>
                <label class="c-item">
                  <span>是否根据dpr生成适合屏幕的高清图片</span>
                  <input type="checkbox" v-model="option.high" />
                  <span>high: {{ option.high }}</span>
                </label>
                <label class="c-item">
                  <span>截图框是否限制在图片里(只有在自动生成截图框时才能生效)</span>
                  <input type="checkbox" v-model="option.centerBox" />
                  <span>centerBox: {{ option.centerBox }}</span>
                </label>
                <label class="c-item">
                  <p>输出图片格式</p>
                  <label>
                    jpg
                    <input type="radio" name="type" value="jpeg" v-model="option.outputType" />
                  </label>
                  <label>
                    png
                    <input type="radio" name="type" value="png" v-model="option.outputType" />
                  </label>
                  <label>
                    webp
                    <input type="radio" name="type" value="webp" v-model="option.outputType" />
                  </label>
                </label>
                <div class="c-item">支持20M以内的图片，最佳尺寸960*640</div>
                <div class="c-item">
                  <a-radio-group v-model="value" @change="onChange">
                    <a-radio :style="radioStyle" :value="0">
                      截图框的比例为300*200 (3:2)
                    </a-radio>
                    <a-radio :style="radioStyle" :value="1">
                      截图框的比例为300*150 (2:1)
                    </a-radio>
                    <a-radio :style="radioStyle" :value="2">
                      截图框的比例为960*640 (3:2)
                    </a-radio>
                    <a-radio :style="radioStyle" :value="3">
                      截图框的比例为960*480 (2:1)
                    </a-radio>
                    <a-radio :style="radioStyle" :value="4">
                      截图框的比例为200*200 (2:1)
                    </a-radio>
                  </a-radio-group>
                </div>
              </div>
            </div>
          </div>
          <div class="model" v-show="model" @click="model = false">
            <div class="model-show">
              <img :src="modelSrc" alt="" style="width: 960px; height: 640px;">
              <img :src="modelSrcTwo" alt="" style="width: 960px; height: 640px;">
            </div>
          </div>
        </a-spin>
      </a-card>
      <!-- <ce ref="cccc"></ce> -->
      <div class="cut_two" style="">
        <vue-cropper
          ref="cropperTwo"
          :img="optionTwo.img"
          :output-size="optionTwo.size"
          :output-type="optionTwo.outputType"
          :info="true"
          :full="optionTwo.full"
          :can-move="optionTwo.canMove"
          :can-move-box="optionTwo.canMoveBox"
          :fixed-box="optionTwo.fixedBox"
          :original="optionTwo.original"
          :auto-crop="optionTwo.autoCrop"
          :auto-crop-width="optionTwo.autoCropWidth"
          :auto-crop-height="optionTwo.autoCropHeight"
          :center-box="optionTwo.centerBox"
          @real-time="realTime"
          :high="optionTwo.high"
        ></vue-cropper>
      </div>
    </a-modal>
  </div>
</template>

<script>
// 使用方法：
// 1,npm install vue-cropper / cnpm install vue-cropper
// 2,main.js里面
//  import VueCropper from 'vue-cropper'
//  Vue.use(VueCropper)
// 在线编辑 例子： https://codepen.io/xyxiao001/pen/wxwKGz
// https://www.jianshu.com/p/85a52da879bb

// import { pictureFile } from '上传文件的接口地址'
// import demo from '@/assets/1.jpg'

export default {
  name: 'UploadImg',
  components: {
  },
  props: {
  },
  data () {
    return {
      model: false,
      show: true,
      lists: [
        {
          img: 'https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png'
        },
        {
          img: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png'
        },
        {
          img: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
        },
        {
          img: 'https://avatars3.githubusercontent.com/u/15681693'
        }
      ],
      isUploadImg: false,
      previews: {},
      option: {
        // img: '',
        img: 'https://avatars3.githubusercontent.com/u/15681693',
        size: 1,
        full: false, // 是否输出原图比例的截图
        outputType: 'png', // 输出图片格式 jpeg png webp
        canMove: true, // 能否拖动图片
        fixedBox: false, // 截图框固定大小
        original: false, // 是否铺满盒子
        canMoveBox: true, // 能否拖动截图框
        autoCrop: true, // 是否自动生成截图框
        // 只有自动截图开启 宽度高度才生效
        autoCropWidth: 960,
        autoCropHeight: 640,
        centerBox: false, // 截图框是否限制在图片里(只有在自动生成截图框时才能生效)
        high: true // 是否根据dpr生成适合屏幕的高清图片
      },
      file: '',
      modelSrc: '',
      spinning: false,
      value: 0,
      radioStyle: {
        display: 'block',
        height: '30px',
        lineHeight: '30px'
      },
      optionTwo: {
        img: '',
        size: 1,
        full: false, // 是否输出原图比例的截图
        outputType: 'jpeg', // 输出图片格式 jpeg png webp
        canMove: true, // 能否拖动图片
        fixedBox: false, // 截图框固定大小
        original: false, // 是否铺满盒子
        canMoveBox: true, // 能否拖动截图框
        autoCrop: true, // 是否自动生成截图框
        // 只有自动截图开启 宽度高度才生效
        autoCropWidth: 300,
        autoCropHeight: 200,
        centerBox: false, // 截图框是否限制在图片里(只有在自动生成截图框时才能生效)
        high: true // 是否根据dpr生成适合屏幕的高清图片
      },
      modelSrcTwo: '',
      nnn: null
    }
  },
  created () {
    // this.add()
  },
  methods: {
    changeImg () {
      console.log(~~(Math.random() * this.lists.length))
      this.option.img = this.lists[~~(Math.random() * this.lists.length)].img
    },
    clearCrop () {
      // clear
      this.$refs.cropper.clearCrop()
    },
    refreshCrop () {
      // clear
      this.$refs.cropper.refresh()
    },
    // 下载
    down (type) {
      // event.preventDefault()
      var aLink = document.createElement('a')
      aLink.download = 'demo'
      // 输出
      if (type === 'blob') {
        this.$refs.cropper.getCropBlob(data => {
          aLink.href = window.URL.createObjectURL(data)
          const img = window.URL.createObjectURL(data)
          aLink.click()
          this.$refs.cccc.add(img)
        })
      } else {
        this.$refs.cropper.getCropData(data => {
          aLink.href = data
          aLink.click()
          this.optionTwo.img = data
          // this.$refs.cccc.add(data)
          this.nnn = setTimeout(() => {
            for (let i = 0; i <= 4; i++) {
              this.$refs.cropperTwo.changeScale(1)
              if (i === 4) {
                clearTimeout(this.nnn)
                this.downTwo('base64')
              }
            }
          }, 1000)
        })
      }
    },
    // Small
    downTwo (type) {
      var aLink = document.createElement('a')
      aLink.download = 'xxxx'
      // 输出
      if (type === 'blob') {
        this.$refs.cropperTwo.getCropBlob(data => {
          aLink.href = window.URL.createObjectURL(data)
          aLink.click()
        })
      } else {
        this.$refs.cropperTwo.getCropData(data => {
          aLink.href = data
          aLink.click()
        })
      }
    },
    onChange (e) {
      const i = e.target.value
      if (i === 0) {
        this.option.autoCropWidth = 300
        this.option.autoCropHeight = 200
      } else if (i === 1) {
        this.option.autoCropWidth = 300
        this.option.autoCropHeight = 150
      } else if (i === 2) {
        this.option.autoCropWidth = 960
        this.option.autoCropHeight = 640
      } else if (i === 3) {
        this.option.autoCropWidth = 960
        this.option.autoCropHeight = 480
      } else if (i === 4) {
        this.option.autoCropWidth = 200
        this.option.autoCropHeight = 200
      }
    },
    add () {
      this.isUploadImg = true
    },
    rotateLeft () {
      this.$refs.cropper.rotateLeft()
    },
    rotateRight () {
      this.$refs.cropper.rotateRight()
    },
    // 实时预览函数
    realTime (data) {
      // console.log(data)
      this.previews = data
    },
    changeScale (num) {
      num = num || 1
      this.$refs.cropper.changeScale(num)
    },
    uploadImg (e, num) {
      console.log(e, num, '222')
      // this.option.img
      var file = e.target.files[0]
      this.file = file
      if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
        alert('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种')
        return false
      }
      var reader = new FileReader()
      reader.onload = e => {
        let data
        if (typeof e.target.result === 'object') {
          // 把Array Buffer转化为blob 如果是base64不需要
          data = window.URL.createObjectURL(new Blob([e.target.result]))
        } else {
          data = e.target.result
        }
        if (num === 1) {
          this.option.img = data
        } else if (num === 2) {
          this.example2.img = data
        }
      }
      // 转化为base64
      // reader.readAsDataURL(file)
      // 转化为blob
      reader.readAsArrayBuffer(file)
    },
    // 确定 压缩并上传
    submit () {
      if (this.option.img === '') {
        this.$message.error('请先上传图片！')
      } else {
        this.spinning = true
        this.$refs.cropper.getCropData(data => {
          this.submitAdd(data)
        })
      }
    },
    async submitAdd (data) {
      const imgItem = data
      const file = this.dataURLtoFile(imgItem, 'pj' + Date.now() + '.jpg')
      const rst = await this.compress(file)
      const fileRst = this.dataURLtoFile(rst, 'pj' + Date.now() + '.jpg')
      const formdata = new FormData()
      formdata.append('file', fileRst)
      if (data) {
        this.spinning = false
        this.$emit('uploadImg', data)
      }
      // pictureFile(formdata).then(res => {
      //   this.spinning = false
      //   if (res.success) {
      //     this.$message.success('上传成功')
      //     this.isUploadImg = false
      //     this.option.img = ''
      //     this.$emit('uploadImg', res.result)
      //   } else {
      //     this.$message.error(res.message)
      //   }
      // })
      this.isUploadImg = false
      this.option.img = ''
    },
    // 预览
    finish (type) {
      // 输出
      // var test = window.open('about:blank')
      // test.document.body.innerHTML = '图片生成中..'
      if (type === 'blob') {
        this.$refs.cropper.getCropBlob(data => {
          var img = window.URL.createObjectURL(data)
          this.model = true
          this.modelSrc = img
          // this.optionTwo.img = img
          // this.$refs.optionTwo.getCropBlob(data => {
          //   var imgTwo = window.URL.createObjectURL(data)
          //   this.model = true
          //   this.modelSrcTwo = imgTwo
          // })
        })
      } else {
        this.$refs.cropper.getCropData(data => {
          this.model = true
          this.modelSrc = data
        })
      }
    },
    // bese64格式转文件类型
    dataURLtoFile (dataUrl, fileName) {
      var arr = dataUrl.split(',')
      var mime = arr[0].match(/:(.*?);/)[1]
      var bstr = atob(arr[1])
      var n = bstr.length
      var u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], fileName, { type: mime })
    },
    // 压缩1
    compress (file) {
      // 压缩图片     uploadImg
      // 使用FileReader对文件对象进行操作
      var that = this
      return new Promise((resolve, reject) => {
        var reader = new FileReader()
        reader.readAsDataURL(file) // 将读取到的文件编码成Data URL
        reader.onload = function () { // 读取完成时
          var replaceSrc = reader.result // 文件输出的内容
          // 调用图片压缩处理方法
          that.compressedImage(
            {
              src: replaceSrc,
              quality: 0.8,
              success: function (src) {
                // console.log('totalList==src', src)
                return resolve(src)
              }
            }
          )
        }
      })
    },
    // 压缩2
    compressedImage (params) {
      // console.log('params', params)
      var initParams = {
        src: params.src || '',
        quality: params.quality || 1
      }
      var image = new Image()
      image.src = initParams.src
      image.onload = function () {
        // 获取图片初始宽高
        var width = image.width
        var height = image.height
        // 判断图片宽度，再按比例设置宽度和高度的值
        // if (width > 1024) {
        //     width = 1024
        //     height = Math.ceil(1024 * (image.height / image.width))
        // }
        // width = 960
        // height = 640
        // 将图片重新画入canvas中
        var canvas = document.getElementById('compressCanvas')
        if (!canvas) { // 如果没有压缩用的canvas 就创建一个canvas画布
          var body = document.body
          canvas = document.createElement('canvas')
          canvas.id = 'compressCanvas'
          canvas.style.position = 'fixed'
          canvas.style.zIndex = '-1'
          canvas.style.opacity = '0'
          canvas.style.top = '-100%'
          canvas.style.left = '-100%'
          body.append(canvas)
        }
        var context = canvas.getContext('2d')
        canvas.width = width
        canvas.height = height
        context.beginPath()
        context.fillStyle = '#ffffff'
        context.fillRect(0, 0, width, height)
        context.fill()
        context.closePath()
        context.drawImage(image, 0, 0, width, height)
        var replaceSrc = canvas.toDataURL('image/jpeg', initParams.quality) // canvas转DataURL(base64格式)
        params.success && params.success(replaceSrc)
      }
    }
  },
  mounted () {
    // console.log(window['vue-cropper'])
  }
}
</script>
<style lang="less" scoped>
/deep/.ant-modal {
  top: 50%;
}
.ant-modal {
  top: 200px!important;
}
.cut {
  width: 1000px;
  height: 700px;
}
.cut_two {
  width:300px;
  height:300px;
  position: absolute;
	left: -999px;
	top: -999px;
}
// 300*200
// /deep/.cut_two .cropper-view-box img {
//   transform: scale(0.427083, 0.427083) translate3d(-772.683px, -330.146px, 0px) rotateZ(0deg) !important;
// }
.c-item {
  max-width: 800px;
  margin: 10px auto;
  margin-top: 20px;
}
.content {
  margin: auto;
  max-width: 1200px;
  margin-bottom: 100px;
}
.test-button {
  // display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
  margin: 10px 0;
}
.btn {
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  background: #fff;
  border: 1px solid #c0ccda;
  color: #1f2d3d;
  text-align: center;
  box-sizing: border-box;
  outline: none;
  margin: 20px 10px 0px 0px;
  padding: 9px 15px;
  font-size: 14px;
  border-radius: 4px;
  color: #fff;
  background-color: #50bfff;
  border-color: #50bfff;
  transition: all 0.2s ease;
  text-decoration: none;
  user-select: none;
}
.des {
  line-height: 30px;
}
code.language-html {
  padding: 10px 20px;
  margin: 10px 0px;
  display: block;
  background-color: #333;
  color: #fff;
  overflow-x: auto;
  font-family: Consolas, Monaco, Droid, Sans, Mono, Source, Code, Pro, Menlo, Lucida, Sans, Type, Writer, Ubuntu, Mono;
  border-radius: 5px;
  white-space: pre;
}
.show-info {
  margin-bottom: 50px;
}
.show-info h2 {
  line-height: 50px;
}
/*.title, .title:hover, .title-focus, .title:visited {
  color: black;
}*/
.title {
  display: block;
  text-decoration: none;
  text-align: center;
  line-height: 1.5;
  margin: 20px 0px;
  background-image: -webkit-linear-gradient(
    left,
    #3498db,
    #f47920 10%,
    #d71345 20%,
    #f7acbc 30%,
    #ffd400 40%,
    #3498db 50%,
    #f47920 60%,
    #d71345 70%,
    #f7acbc 80%,
    #ffd400 90%,
    #3498db
  );
  color: transparent;
  -webkit-background-clip: text;
  background-size: 200% 100%;
  animation: slide 5s infinite linear;
  font-size: 40px;
}
.test {
  height: 500px;
}
.model {
  position: fixed;
  z-index: 10;
  width: 100vw;
  height: 100vh;
  overflow: auto;
  top: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.8);
}
.model-show {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
}
.model img {
  display: block;
  margin: auto;
  max-width: 80%;
  user-select: none;
  background-position: 0px 0px, 10px 10px;
  background-size: 20px 20px;
  background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%),
    linear-gradient(45deg, #eee 25%, white 25%, white 75%, #eee 75%, #eee 100%);
}
.c-item {
  display: block;
  user-select: none;
  width: 700px;
  margin: auto;
}
/deep/.ant-modal-content {
  min-width: 1800px;
}
</style>
